package org.jeecg.modules.activiti.web;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.oa.enums.PendingSubStateEnum;
import org.jeecg.common.oa.utils.OaPendingUtils;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.activiti.entity.ActBusiness;
import org.jeecg.modules.activiti.entity.ActZprocess;
import org.jeecg.modules.activiti.enums.ResultEnum;
import org.jeecg.modules.activiti.enums.StatusEnum;
import org.jeecg.modules.activiti.service.IActBusinessService;
import org.jeecg.modules.activiti.service.IActZprocessService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author PanMeiCheng
 * @version 1.0
 * @date 2020-04-02
 */
@RestController
@RequestMapping("/actBusiness")
@Slf4j
@Transactional
@Api(tags = "流程")
public class ActBusinessController {
    @Autowired
    IActBusinessService actBusinessService;
    @Autowired
    IActZprocessService actZprocessService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    ISysBaseAPI sysBaseAPI;
    @Autowired
    private HistoryService historyService;

    /*获取业务表单信息*/
    @AutoLog(value = "流程-获取业务表单信息")
    @ApiOperation(value = "流程-获取业务表单信息", notes = "获取业务表单信息")
    @RequestMapping(value = "/getForm", method = RequestMethod.GET)
    public Result getForm(@ApiParam(value = "类型：0查看 1编辑", required = true) Integer type,
                          @ApiParam(value = "流程表数据ID", required = false) String executionId,
                          @ApiParam(value = "业务表数据id", required = false) String tableId,
                          @ApiParam(value = "业务表数据id", required = false) String businessId,
                          @ApiParam(value = "业务表名", required = false) String tableName) {


//        if (StringUtils.isBlank(executionId)) {
//            return Result.error("参数缺省！");
//        }
//        ActBusiness actBusiness = actBusinessService.getByProcInstId(executionId);
//        return Result.ok(actBusiness);
        if (type == null) {
            return Result.error("参数缺省！");
        }
        ActBusiness actBusiness = null;
        if (type.intValue() == 1) {
            if (StringUtils.isBlank(tableId) || StringUtils.isBlank(tableName)) {
                return Result.error("参数缺省！");
            }
            Map<String, Object> applyForm = actBusinessService.getApplyForm(tableId, tableName);
            actBusiness = new ActBusiness();
            actBusiness.setDataMap(applyForm);
        } else {
            if (StringUtils.isBlank(executionId) && StringUtils.isBlank(businessId)) {
                return Result.error("参数缺省！");
            }
            if (StringUtils.isNotBlank(businessId)){
                actBusiness = actBusinessService.getById(businessId);
            } else {
                actBusiness = actBusinessService.getByProcInstId(executionId);
            }
            if (actBusiness != null && StringUtils.isNotBlank(actBusiness.getData())){
                actBusiness.setDataMap(JSON.parseObject(actBusiness.getData(), Map.class));
                actBusiness.setData("");
            }
            if (actBusiness != null && StringUtils.isNotBlank(actBusiness.getOldData())){
                actBusiness.setOldDataMap(JSON.parseObject(actBusiness.getOldData(), Map.class));
                actBusiness.setOldData("");
            }
//            //如果流程在进行中查询进行中的记录 否则查询历史记录
//            if (actBusiness != null && actBusiness.getStatus() != null && actBusiness.getStatus().intValue() == StatusEnum.STATUS_DEALING.getStatus()) {
//                applyForm = runtimeService.getVariables(executionId);
//            } else {
//                List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery().executionId(executionId).list();
//                if (list != null) {
//                    Map<String, Object> finalApplyForm = applyForm;
//                    list.stream().forEach(e -> {
//                        finalApplyForm.put(e.getVariableName(), e.getValue());
//                    });
//                }
//            }
        }
        return Result.ok(actBusiness);
    }

    /*添加申请草稿状态*/
    @AutoLog(value = "流程-添加申请草稿状态")
    @ApiOperation(value = "流程-添加申请草稿状态", notes = "业务表单参数数据一并传过来！")
    @PostMapping(value = "/add")
    public Result add(@RequestBody Map<String, Object> map,
                      HttpServletRequest request) {
        //返回主键id
        String id = actBusinessService.saveOrUpdateAndUpdateApplyForm(null, map);
        return Result.ok(id);
    }

    /*修改业务表单信息*/
    @AutoLog(value = "流程-修改业务表单信息")
    @ApiOperation(value = "流程-修改业务表单信息", notes = "业务表单参数数据一并传过来!")
    @RequestMapping(value = "/editForm", method = RequestMethod.POST)
    public Result editForm(@RequestBody Map<String, Object> map,
                           HttpServletRequest request) {
        /*保存业务表单数据到数据库表*/
        if (map.get("id") == null || StringUtils.isBlank(map.get("id").toString())){
            return Result.error("信息不存在！");
        }
        actBusinessService.saveOrUpdateAndUpdateApplyForm(map.get("id").toString(), map);
        return Result.ok();
    }

    /*通过id删除草稿状态申请*/
    @AutoLog(value = "流程-通过id删除草稿状态申请")
    @ApiOperation(value = "流程-通过id删除草稿状态申请", notes = "通过id删除草稿状态申请")
    @RequestMapping(value = "/delByIds", method = RequestMethod.POST)
    public Result delByIds(@ApiParam(value = "流程扩展表id，多个,号相连", required = true) String ids) {

        for (String id : ids.split(CommonConstant.DEFAULT_SEPARATOR)) {
            ActBusiness actBusiness = actBusinessService.getById(id);
//            if (actBusiness.getStatus() != StatusEnum.STATUS_TO_APPLY.getStatus()) {
//                return Result.error("删除失败, 仅能删除草稿状态的申请");
//            }
            // 删除关联业务表
//            actBusinessService.deleteBusiness(actBusiness.getTableName(), actBusiness.getTableId());
            actBusinessService.updateBusinessStatus(actBusiness.getTableName(), actBusiness.getTableId(), -1, "");
            actBusinessService.removeById(id);
        }
        return Result.ok("删除成功");
    }

    /*提交申请 启动流程*/
    @AutoLog(value = "流程-提交申请 启动流程")
    @ApiOperation(value = "流程-提交申请 启动流程", notes = "提交申请 启动流程。")
    @RequestMapping(value = "/apply", method = RequestMethod.POST)
    public Result apply(ActBusiness act) {
        System.out.println(act.getId()+"新的楼层ID");

        ActBusiness actBusiness = actBusinessService.getById(act.getId());
        if (actBusiness == null) {
            return Result.error("流程信息错误");
        }
        act.setTableId(actBusiness.getTableId());

        act.setData(actBusiness.getData());
        String processInstanceId = actZprocessService.startProcess(act);
        actBusiness.setProcInstId(processInstanceId);
        actBusiness.setStatus(StatusEnum.STATUS_DEALING.getStatus());
        actBusiness.setResult(ResultEnum.RESULT_DEALING.getStatus());
        actBusiness.setApplyTime(new Date());
        actBusinessService.updateById(actBusiness);
        //修改业务表的流程字段
        actBusinessService.updateBusinessStatus(actBusiness.getTableName(), actBusiness.getTableId(), actBusiness.getResult(), "启动");
        return Result.ok("操作成功");
    }

    /*撤回申请*/
    @AutoLog(value = "流程-撤回申请")
    @ApiOperation(value = "流程-撤回申请", notes = "撤回申请")
    @RequestMapping(value = "/cancel", method = RequestMethod.POST)
    public Result<Object> cancel(@ApiParam(value = "流程扩展表id", required = true) @RequestParam String id,
                                 @ApiParam(value = "流程实例id", required = true) @RequestParam String procInstId,
                                 @ApiParam(value = "撤销理由原因说明", required = false) @RequestParam(required = false) String reason) {

        Task task =taskService.createTaskQuery().processInstanceId(procInstId).singleResult();
//        List<Task> list = taskService.createTaskQuery().processInstanceId(procInstId).list();
        if (StrUtil.isBlank(reason)) {
            reason = "";
        }
        runtimeService.deleteProcessInstance(procInstId, "canceled-" + reason);
        ActBusiness actBusiness = actBusinessService.getById(id);
        actBusiness.setStatus(StatusEnum.STATUS_CANCELED.getStatus());
        actBusiness.setResult(ResultEnum.RESULT_TO_SUBMIT.getStatus());
        actBusinessService.updateById(actBusiness);
        //修改业务表的流程字段
        actBusinessService.updateBusinessStatus(actBusiness.getTableName(), actBusiness.getTableId(), -1, "撤回");
        OaPendingUtils.sendCompletePending(task.getId(), PendingSubStateEnum.CANCEL.getStatus());
        return Result.ok("操作成功");
    }

    /**/
    @AutoLog(value = "流程-流程列表")
    @ApiOperation(value = "流程-流程列表", notes = "流程列表，登录用户的流程列表")
    @RequestMapping(value = "/listData", method = RequestMethod.GET)
    public Result listData(ActBusiness param, HttpServletRequest request) {
        LambdaQueryWrapper<ActBusiness> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(ActBusiness::getCreateTime);
        if (StrUtil.isNotBlank(param.getTitle())) queryWrapper.like(ActBusiness::getTitle, param.getTitle());
        if (param.getStatus() != null) queryWrapper.eq(ActBusiness::getStatus, param.getStatus());
        //多个
        String statuss = request.getParameter("statuss");
        if (StrUtil.isNotBlank(statuss)) {
            queryWrapper.in(ActBusiness::getStatus, StrUtil.split(statuss, CommonConstant.DEFAULT_SEPARATOR));
        }
        if (param.getResult() != null) queryWrapper.eq(ActBusiness::getResult, param.getResult());
        String createTime_begin = request.getParameter("createTime_begin");
        if (StrUtil.isNotBlank(createTime_begin))
            queryWrapper.ge(ActBusiness::getCreateTime, createTime_begin);
        String createTime_end = request.getParameter("createTime_end");
        if (StrUtil.isNotBlank(createTime_end))
            queryWrapper.le(ActBusiness::getCreateTime, createTime_end);

        LoginUser loginUser = JwtUtil.getLoginUser();
        queryWrapper.eq(ActBusiness::getUserId, loginUser.getUsername());
        //流程类型
        String type = request.getParameter("type");
        if (StrUtil.isNotBlank(type)) {
            List<String> actBusinessIdsByType = actBusinessService.listByTypeApp(type);
            if (actBusinessIdsByType.size() == 0) { // 没有符合的 目的是上下面的查询条件也查不到
                queryWrapper.in(ActBusiness::getId, Lists.newArrayList(""));
            } else {
                queryWrapper.in(ActBusiness::getId, actBusinessIdsByType);
            }
        }
        List<ActBusiness> actBusinessList = actBusinessService.list(queryWrapper);

        // 是否需要业务数据
        String needData = request.getParameter("needData");
        actBusinessList.forEach(e -> {
            if (StrUtil.isNotBlank(e.getProcDefId())) {
                ActZprocess actProcess = actZprocessService.getById(e.getProcDefId());
                e.setRouteName(actProcess.getRouteName());
                e.setProcessName(actProcess.getName());
            }
            if (e.getStatus() != null && e.getStatus().intValue() == StatusEnum.STATUS_DEALING.getStatus()) {
                // 关联当前任务
                List<Task> taskList = taskService.createTaskQuery().processInstanceId(e.getProcInstId()).list();
                if (taskList != null && taskList.size() == 1) {
                    e.setCurrTaskName(taskList.get(0).getName());
                } else if (taskList != null && taskList.size() > 1) {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < taskList.size() - 1; i++) {
                        sb.append(taskList.get(i).getName() + "、");
                    }
                    sb.append(taskList.get(taskList.size() - 1).getName());
                    e.setCurrTaskName(sb.toString());
                }
            }
            if (StrUtil.equals(needData, "true")) { // 需要业务数据
                Map<String, Object> applyForm = actBusinessService.getApplyForm(e.getTableId(), e.getTableName());
                e.setDataMap(applyForm);
            }
        });
        return Result.ok(actBusinessList);
    }
}
